package cn.mujiankeji.mbrowser.功能.下载

import android.content.Context
import android.util.Log
import cn.mujiankeji.mbrowser.功能.下载.模型.下载任务
import cn.mujiankeji.mbrowser.功能.下载.模型.下载引擎类型
import cn.mujiankeji.mbrowser.功能.下载.模型.下载状态
import cn.mujiankeji.mbrowser.功能.下载.模型.下载类型
import cn.mujiankeji.mbrowser.功能.下载.仓库.下载仓库接口
import cn.mujiankeji.mbrowser.功能.下载.引擎.默认下载引擎
import io.ktor.client.HttpClient
import kotlinx.coroutines.flow.Flow
import java.util.Date
import java.util.UUID

class 下载管理器实现(
    private val context: Context, // 用于发送Intent等
    private val 下载仓库: 下载仓库接口,
    private val httpClient: HttpClient // 用于创建下载引擎
    // 未来可能注入下载服务实例的引用，或者通过其他方式与服务通信
) : 下载管理器接口 {

    private val TAG = "下载管理器实现"

    // 引擎实例可以按需创建，或者在这里维护一个池 (暂时按需创建)
    private val ktorDownloadEngine by lazy { 默认下载引擎(httpClient) }
    //private val m3u8DownloadEngine by lazy { M3u8DownloadEngine(httpClient, context) } // 假设M3U8引擎可能需要context

    override suspend fun 请求新下载(
        url: String,
        文件名: String,
        目标文件夹: String,
        请求头: Map<String, String>?,
        userAgent: String?
    ): String {
        // 1. 生成任务ID
        val 任务Id = UUID.randomUUID().toString()

        // 2. 确定文件名
        val 实际文件名 = 文件名

        // 3. 确定目标路径 (后续从设置中获取默认路径)
        val 实际目标路径 = 目标文件夹 // ?: context.getExternalFilesDir("downloads")?.absolutePath ?: "/mnt/sdcard/Download"


        // 4. 判断下载类型（普通, M3U8等） -> 这会影响引擎选择
        // 简单示例：先假设都是普通下载或根据url简单判断
        val 引擎类型 = if (url.contains(".m3u8", ignoreCase = true)) {
            下载引擎类型.KTOR_M3U8
        } else {
            下载引擎类型.KTOR
        }
        val 下载类型 = if (引擎类型 == 下载引擎类型.KTOR_M3U8) 下载类型.M3U8 else 下载类型.普通


        // 5. 创建下载任务对象
        val 新任务 = 下载任务(
            id = 任务Id,
            url = url,
            文件名 = 实际文件名,
            目标文件夹 = 实际目标路径,
            状态 = 下载状态.等待中, // 初始状态
            创建时间 = Date(),
            引擎类型 = 引擎类型,
            类型 = 下载类型,
            请求头 = 请求头 ?: emptyMap(),
            UserAgent = userAgent
            // 其他字段使用默认值
        )

        // 6. 将任务添加到仓库
        下载仓库.添加下载任务(新任务)
        // 7. 通知下载服务开始处理该任务 (通过Intent或直接调用服务方法)
        // 例如，通过发送Intent给下载服务
        val intent = android.content.Intent(context, 下载服务::class.java).apply {
            action = 下载服务.开始下载 // 需要在服务中定义此Action
            putExtra(下载服务.EXTRA_TASK_ID, 任务Id)
        }
        context.startService(intent)
        return 任务Id
    }

    override suspend fun 暂停下载(任务Id: String) {
        // 通知下载服务暂停任务
        val intent = android.content.Intent(context, 下载服务::class.java).apply {
            action = 下载服务.暂停下载 // 已有此Action
            putExtra(下载服务.EXTRA_TASK_ID, 任务Id)
        }
        context.startService(intent)
    }

    override suspend fun 恢复下载(任务Id: String) {
        // 通知下载服务恢复任务
        val intent = android.content.Intent(context, 下载服务::class.java).apply {
            action = 下载服务.恢复下载 // 已有此Action
            putExtra(下载服务.EXTRA_TASK_ID, 任务Id)
        }
        context.startService(intent)
    }

    override suspend fun 取消下载(任务Id: String) {
        Log.d(TAG, "请求取消下载: $任务Id")
        // 通知下载服务取消任务
        val intent = android.content.Intent(context, 下载服务::class.java).apply {
            action = 下载服务.取消下载 // 已有此Action
            putExtra(下载服务.EXTRA_TASK_ID, 任务Id)
        }
        context.startService(intent)
    }

    override fun 获取下载任务状态Flow(任务Id: String): Flow<下载任务?> {
        return 下载仓库.获取下载任务(任务Id) // 与接口方法名保持一致
    }

    override fun 获取所有下载任务Flow(): Flow<List<下载任务>> {
        return 下载仓库.获取所有下载任务()
    }

    override fun 获取活动下载任务Flow(): Flow<List<下载任务>> {
        // 活动状态包括：等待中, 正在下载, 已暂停
        return 下载仓库.获取活动下载任务()
    }

    override fun 获取已完成下载任务Flow(): Flow<List<下载任务>> {
        return 下载仓库.获取已完成下载任务()
    }


    override suspend fun 删除下载记录(任务Id: String, 同时删除文件: Boolean) {
        val 任务 = 下载仓库.获取下载任务快照(任务Id) // 获取一次性快照
        if (任务 != null && 同时删除文件) {
            try {
                val file = java.io.File(任务.目标文件夹, 任务.文件名)
                if (file.exists()) {
                    if (file.delete()) {
                        Log.i(TAG, "文件已删除: ${file.absolutePath}")
                    } else {
                        Log.w(TAG, "文件删除失败: ${file.absolutePath}")
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "删除文件时出错: ${任务.文件名}", e)
            }
        }
        下载仓库.删除下载任务(任务Id)
    }

    override suspend fun 清空已完成下载记录(同时删除文件: Boolean) {
        Log.d(TAG, "请求清空已完成下载记录, 同时删除文件: $同时删除文件")
        val completedTasks = 下载仓库.获取特定状态任务快照列表(下载状态.已完成.ordinal) // 与接口方法名保持一致
        if (同时删除文件) {
            completedTasks.forEach { 任务 ->
                try {
                    val file = java.io.File(任务.目标文件夹, 任务.文件名)
                    if (file.exists() && file.isFile) {
                        val deleted = file.delete()
                        if (!deleted) {
                            Log.w(TAG, "无法删除文件: ${file.absolutePath}")
                        }
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "清空已完成任务时删除文件出错: ${任务.文件名}", e)
                }
            }
        }
        
        // 逐个删除任务记录
        completedTasks.forEach { 任务 -> 
            下载仓库.删除下载任务(任务.id)
        }
        Log.i(TAG, "已清空 ${completedTasks.size} 个已完成任务的记录。")
    }
}

